/**
 *  header包含顶部的🍔按钮和搜索框
 */

import React from 'react';
import { connect } from 'react-redux';
import * as action from '../../redux/action';
import * as css from './style';
import { fetch, handleError, isMobile } from '../../utils/utils';

class Header extends React.Component {
    render() {
        let keyword = this.props.keyword;

        return (
            <div className={ css.header } data-type="header">
                <Hamburger mvUserpanel={ this.props.spreadUserPanel }
                    hideAside={ this.props.hideAside }/>

                <a href="/" className={ css.logo }></a>

                <Search getsearch={ this.props.getBookByKeyword }
                    clearsearch={ this.props.clearAllBook }
                    sendMessage={ this.props.sendMessage }
                    defaultKeyword={ keyword } />
            </div>
        )
    }
}


/**
 *  Hamburger button.
 *  @props mvUserpanel: redux action @spreadUserPanel
 *  @props hideAside: redux action @hideAside
 */
class Hamburger extends React.Component {

    constructor(props) {
        super(props);
        this.canClick = true;
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick(e) {
        e.preventDefault();

        // 当点击时还处于上一次点击的延迟范围内，则本次点击无效。
        if (!this.canClick) return false;
        this.canClick = false;

        // 如果设备是移动设备，则点击时隐藏aside
        if (isMobile) {
            this.props.hideAside();
        }

        const target = this.refs.hambtn;

        let t = setTimeout(() => {

            // classList.remove not support IE<=9.
            target.classList.remove(css.hamburger_act);

            this.canClick = true;
            clearTimeout(t);
        }, 600);

        this.props.mvUserpanel();

        // classList.add not support IE<=9.
        target.classList.add(css.hamburger_act);
    }

    render() {
        return (
            <div className={ css.hamburger } onClick={ this.handleClick }
                onTouchStart={ this.handleClick } ref="hambtn">
            </div>
        )
    }
}


/**
 *  book search input.
 *  @props getsearch: redux action getBookByKeyword
 *  @props clearsearch: redux action clearAllBook
 *  @props sendMessage: redux action sendMessage
 *  @props defaultKeyword: string or undefined
 */
class Search extends React.Component {

    constructor(props) {
        super(props);
        this.handleInput = this.handleInput.bind(this);
    }

    componentDidMount() {
        // 如果有defaultKeyword传入，则直接搜索它，用于页面加载时
        // 需要直接显示某个关键字的结果
        if (this.props.defaultKeyword) {
            this.refs.i.value = this.props.defaultKeyword;
            this.handleInput();
        }
    }

    handleInput() {

        // 删除关键字首尾空格
        let key = this.refs.i.value.trim();

        // 当前关键字与上次关键字相同，出现在输入可trim字符的情况下
        if (key === this.lastKeyword) return false;

        // 若运行到此，则本次关键字成为上次关键字
        // 同时取消上次请求（若尚未返回数据）
        this.lastKeyword = key;
        this.lastReq && this.lastReq.abort();

        if (key.length === 0) {
            this.props.clearsearch();
            return false;
        }

        // IE >=10 does not support multiple parameters.
        // so use className write class name string.
        this.refs.l.className = `${ css.iconloading } ${css.loading}`;

        // search request
        this.lastReq = fetch({
            do: 'search',
            keyword: key,
            page: 1
        }).done(res => {
            if (res.all > 0) {
                this.props.sendMessage(`找到 ${res.all} 本与 ${res.keywords} 有关的书，共 ${res.allpage} 页。`);
            } else {
                this.props.sendMessage(`找不到与 ${res.keywords} 有关的书，请尝试其他关键词。`);
            }
            this.props.getsearch(res);
        }).fail(handleError.bind(this))
            .always(() => {
                this.refs.l.className = 'icon-loading';
            })
    }

    render() {
        return (
            <div className={ css.search }>
                <i className={ css.iconsearch }></i>
                <input type="text" placeholder="输入关键字开始查询" ref="i"
                    autoFocus="autofocus" maxLength="40" onChange={ this.handleInput }/>
                <i className={ css.iconloading } ref="l"></i>
            </div>
        )
    }
}

export default connect(state => ({
    // search keyword.
    keyword: state.BOOK.getIn(['unrender', 'keyword'])
}), action)(Header);
